package fr.labri.macchiato.ui.preferences;

import java.util.ArrayList;
import java.util.List;

import com.smartgwt.client.util.EventHandler;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.DropOverEvent;
import com.smartgwt.client.widgets.events.DropOverHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;

import fr.labri.macchiato.core.model.BusinessEntity;
import fr.labri.macchiato.core.model.UserPreferences;
import fr.labri.macchiato.core.service.Services;
import fr.labri.macchiato.core.technical.Callback;

/**
 * A widget that allows the user to choose his preferred {@link BusinessEntity}
 * If the user has chosen to save permanently his preferences, so the logos that
 * have been dropped into the selectedBusinessEntities layout, should remain
 * after close.
 * 
 * @author Michelle AVOMO
 * 
 * 
 */

public class BusinessEntityWidget extends VLayout implements PreferencesWidget {

	private static final String BORDER_COLOR = "#008A77";
	private static final String SELECTED_SHOPS = "<i> Magasins favoris</i>";
	private static final String LABEL = "<b>Déplacez les images pour sélectionner vos magasins préférés</b>";
	private static final String WIDGET_TITLE = "Mes magasins préférés";
	private HLayout selectedBusinessEntities;
	private HLayout availableBusinessEntities;

	private List<BusinessEntity> favoriteBusinessEntities;

	/**
	 * Constructor
	 */
	public BusinessEntityWidget() {
		favoriteBusinessEntities = new ArrayList<BusinessEntity>();
		setWidth100();

		Label textLabel = new Label(LABEL);
		textLabel.setWidth(600);

		addMember(textLabel);

		createListBusinessEntityContainer();
		createPreferedBusinessEntitiesContainer();
		eventsAfterDropping();

		// Adding the components to the HLAyout
		addMember(availableBusinessEntities);
		addMember(selectedBusinessEntities);

	}

	/******************************* PRIVATE METHODS ************************************************/

	/**
	 * What should occur after the user dropped a given logo into the
	 * selectedBusinessEntities container.
	 */
	private void eventsAfterDropping() {
		selectedBusinessEntities.addDropOverHandler(new DropOverHandler() {
			public void onDropOver(DropOverEvent event) {
				selectedBusinessEntities.setBorder(BORDER_COLOR);
				getPreferedBusinessEntities();
			}

		});

		availableBusinessEntities.addDropOverHandler(new DropOverHandler() {

			public void onDropOver(DropOverEvent event) {
				favoriteBusinessEntities.remove(getDraggedBusinessEntity());

			}
		});
	}

	/**
	 * Creates the container for the dynamic container with the prefered objects
	 */
	private void createPreferedBusinessEntitiesContainer() {
		// Selected providers
		selectedBusinessEntities = new HLayout(10);
		selectedBusinessEntities.setContents(SELECTED_SHOPS);

		// Properties for the selected providers
		selectedBusinessEntities.setLayoutMargin(20);
		selectedBusinessEntities.setLeft(120);
		selectedBusinessEntities.setTop(10);
		selectedBusinessEntities.setShowEdges(false);
		selectedBusinessEntities.setCanAcceptDrop(true);
		selectedBusinessEntities.setAnimateMembers(true);
		selectedBusinessEntities.setShowDragPlaceHolder(true);
		selectedBusinessEntities.setDropLineThickness(5);
		selectedBusinessEntities.setBorder("3px solid #008A77");

		selectedBusinessEntities
				.setTitle("Vos magasins favoris. Gissez-deposez pour retirer de la liste");

	}

	/**
	 * Creates the container with the list of logos dynamic charged from the
	 * database
	 */

	private void createListBusinessEntityContainer() {

		// List of the providers
		availableBusinessEntities = new HLayout(10);
		availableBusinessEntities.setContents("<i>Liste des magasins </i>");

		// properties for the list of the selected providers
		availableBusinessEntities.setLayoutMargin(20);
		availableBusinessEntities.setCanAcceptDrop(true);
		availableBusinessEntities.setAnimateMembers(true);
		availableBusinessEntities.setDropLineThickness(5);
		availableBusinessEntities.setBorder("3px solid #adcf4f");

	}

	/**
	 * Retrieves logos from the database and adds them into the container
	 */
	private void addLogosToList() {

		Services.getInstance()
				.getBusinessEntityService()
				.getDetailsBusinessEntities(
						new Callback<List<BusinessEntity>>() {

							@Override
							public void onCallback(List<BusinessEntity> result) {
									for (BusinessEntity be : result) {
										if (!favoriteBusinessEntities.contains(be)) {
											BusinessEntityLogo logo = new BusinessEntityLogo(
													be);
											availableBusinessEntities
													.addMember(logo);
										}
									}

							}

						});
	}

	/**
	 * Retrieves the id of the favorite shops
	 */
	private List<BusinessEntity> getPreferedBusinessEntities() {

		BusinessEntity bu = getDraggedBusinessEntity();

		if (!favoriteBusinessEntities.contains(bu))
			favoriteBusinessEntities.add(bu);

		return favoriteBusinessEntities;
	}

	/******************************* METHODS FROM THE INTERFACE ************************************************/

	public void addToParent(Window preference) {
		preference.addItem(this);

	}

	public void collectUserPreferences(UserPreferences preference) {
		preference.setFavoriteBusinessEntities(favoriteBusinessEntities);
	}

	public Boolean isValid() {
		return true;
	}

	public void restoreUserPreferences(UserPreferences preferences) {
		availableBusinessEntities.removeMembers(availableBusinessEntities
				.getMembers());
		selectedBusinessEntities.removeMembers(selectedBusinessEntities
				.getMembers());

		if (preferences.getFavoriteBusinessEntities() != null
				&& !preferences.getFavoriteBusinessEntities().isEmpty())
			setFavoriteBusinessEntities(preferences.getFavoriteBusinessEntities());
		addLogosToList();

	}

	/***************************************************** PRIVATE METHODS **************************************************************/

	private void setFavoriteBusinessEntities(
			List<BusinessEntity> favoriteBusinessEntities) {
		this.favoriteBusinessEntities = favoriteBusinessEntities;
		for (BusinessEntity bu : favoriteBusinessEntities) {
			BusinessEntityLogo logo = new BusinessEntityLogo(bu);
			selectedBusinessEntities.addMember(logo);
		}
	}

	private BusinessEntity getDraggedBusinessEntity() {
		BusinessEntityLogo ltd = (BusinessEntityLogo) EventHandler
				.getDragTarget();

		BusinessEntity bu = ltd.getBusinessEntity();

		return bu;
	}

	@Override
	public String getTitle() {
		return WIDGET_TITLE;
	}
}
